
#include<pthread.h>

#define LL_ADD(item, list) do{ \                 //头插法
    item->prev = NULL;          \
    item->next = list;         \
    if (list != NULL) list->prev = item;          \
    list = item;                \
 } while (0);
 #define LL_REMOVE (item, list) do {
    if (item->prev != NULL) item->prev->next = item->next;  \
    if (item->next != NULL) item->next->prev = item->prev; \
    if (list == item) list = item->next;\
    item->prev = NULL     \
    item->next = NULL;    \
 }while (0);


struct nWorker{                    //执行队列
    pthread_t thread;
    struct nManager pool;
    struct nWorker *prev;    //前 
    struct nWorker *next;    //后  形成双向链表
};

struct nJob{                     //任务队列
    void (*func)(struct nJob *job);  //  接收不同的任务函数
    void *user_data;    
    struct nJob *prev;    //前 
    struct nJob *next;    //后  形成双向链表

};

struct nManager{
    struct nWorker *workers;
    struct nJob *jobs;
    pthread_cond_t jobs_cond;  //等待一个条件的满足  也就是等待任务到来，唤醒工作线程
    pthread_mutex_t job_mutex;  //任务队列锁，任务是工作线程的临界区，要加锁保护

}

typedef struct nManager nThreadPool;
static void *nThreadCallback(void *arg) {
    struct NWORKER *worker = (struct NWORKER*) arg;
    while(1){
        pthread_mutex_lock(&worker->pool->jobs_mutex));
        while (worker->pool->jobs == NULL) {
            pthread_cond_wait(&worker->pool->jobs_cond, &worker->pool->jobs_mutex);
        }
        struct NJOB *job = worker->pool->jobs; 
        LL_REMOVE(job, worker->pool->jobs);
        pthread_mutex_un  lock(&worker->pool->jobs_mutex));
        job->func(job->user_data);
    }


}
// Thread Pool Create, API 
int ThreadPoolCreate(nThreadPool *pool, int numwokers){
    if (numlworkers < 1)   //如果值小于1，默认创建一个工作线程
        numworkers = 1; 
    if (pool = NULL) return -1;
    memset (pool, 0, sizeof (nThreadPool)); //初始pool指针对应的空间
    pthread_cond_t blank_cond = PTHREAD_COND_INITIALIZER;           //初始化条件变量
    memcpy(&pool->jobs_cond, &blank_cond, sizeof (pthread_cond_t));

    pthread_mutex_t blank_mutex = PTHREAD_MUTEX_INITIALIZER;        //初始化互斥量
    memcpy(&pool->jobs_mutex, &blank_mutex, sizeof (pthread_mutex_t));
    int i=0;
    for (i=0;i <numworkers;i ++) {
        struct nWorker *worker = (struct nWorkwer*)malloc(sizeof(struct nWorkwer));
        if (worker == NULL){
            perror("malloc"); 
            return -2; 
        }
        memset (worker, 0, sizeof (struct nWorker) ); 
        worker->pool = pool;
        int ret = pthread_create(worker->thread, NULL, nThreadCallback,worker) ;
        if (ret) {
            perror ("pthread_create"); 
            free(worker); 
            return -3;
        } 
        LL_ADD(worker,pool->workers);

    } 

}
int nThreadPoolDestroy(nThreadPool *pool){   // 销毁线程池
    struct NWORKER *worker = NULL; 
    for (worker = pool->workers; worker != NULL; worker = worker->next) {
        worker->terminate = 1;
    }
    pthread_mutex_lock(&pool->jobs_mutex); 
    pthread_cond_broadcast(&pool->jobs_cond); 
     pthread_mutex_unlock(&pool->jobs_mutex);

}
void nThreadPoolPush(nThreadPool *pool, struct nJob *job){   //向线程池添加任务
    pthread_mutex_lock(&pool->jobs_mutex); 
    LL_ADD(job, pool->jobs); 
    pthread_cond_signal(&pool->jobs_cond); 
    pthread_mutex_unlock(&pool->jobs_mutex);
}
 